JBoss Community Archive (Read Only)

WildFly 9

Seam 2 Booking Application - Migration of Binaries from EAP5.1 to WildFly

This is a step-by-step how-to guide on porting the Seam Booking application binaries from EAP5.1 to WildFly 8. Although there are better approaches for migrating applications, the purpose of this document is to show the types of issues you might encounter when migrating an application and how to debug and resolve those issues.

For this example, the application EAR is deployed to the JBOSS_HOME/standalone/deployments directory with no changes other than extracting the archives so we can modify the XML files contained within them.

Step 1: Build and deploy the EAP5.1 version of the Seam Booking application

  1. Build the EAR

        cd /EAP5_HOME/jboss-eap5.1/seam/examples/booking
        ~/tools/apache-ant-1.8.2/bin/ant explode
  2. Copy the EAR to the JBOSS_HOME deployments directory:

        cp -r EAP5_HOME/jboss-eap-5.1/seam/examples/booking/exploded-archives/jboss-seam-booking.ear AS7_HOME/standalone/deployments/
        cp -r EAP5_HOME/jboss-eap-5.1/seam/examples/booking/exploded-archives/jboss-seam-booking.war AS7_HOME/standalone/deployments/jboss-seam.ear
        cp -r EAP5_HOME/jboss-eap-5.1/seam/examples/booking/exploded-archives/jboss-seam-booking.jar AS7_HOME/standalone/deployments/jboss-seam.ear
  3. Start the WildFly server and check the log. You will see:

        INFO [org.jboss.as.deployment] (DeploymentScanner-threads - 1) Found jboss-seam-booking.ear in deployment directory. To trigger deployment create a file called jboss-seam-booking.ear.dodeploy
  4. Create an empty file with the name jboss-seam-booking.ear.dodeploy and copy it into the deployments directory. In the log, you will now see the following, indicating that it is deploying:

        INFO [org.jboss.as.server.deployment] (MSC service thread 1-1) Starting deployment of "jboss-seam-booking.ear"
        INFO [org.jboss.as.server.deployment] (MSC service thread 1-3) Starting deployment of "jboss-seam-booking.jar"
        INFO [org.jboss.as.server.deployment] (MSC service thread 1-6) Starting deployment of "jboss-seam.jar"
        INFO [org.jboss.as.server.deployment] (MSC service thread 1-2) Starting deployment of "jboss-seam-booking.war"

At this point, you will first encounter your first deployment error. In the next section, we will step through each issue and how to debug and resolve it.

Step 2: Debug and resolve deployment errors and exceptions

First Issue: java.lang.ClassNotFoundException: javax.faces.FacesException

When you deploy the application, the log contains the following error:

ERROR \[org.jboss.msc.service.fail\] (MSC service thread 1-1) MSC00001: Failed to start service jboss.deployment.subunit."jboss-seam-booking.ear"."jboss-seam-booking.war".POST_MODULE:
org.jboss.msc.service.StartException in service jboss.deployment.subunit."jboss-seam-booking.ear"."jboss-seam-booking.war".POST_MODULE:
Failed to process phase POST_MODULE of subdeployment "jboss-seam-booking.war" of deployment "jboss-seam-booking.ear"
    (.. additional logs removed ...)
Caused by: java.lang.ClassNotFoundException: javax.faces.FacesException from \[Module "deployment.jboss-seam-booking.ear:main" from Service Module Loader\]
    at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:191)

What it means:

The ClassNotFoundException indicates a missing dependency. In this case, it can not find the class javax.faces.FacesException and you need to explicitly add the dependency.

How to resolve it:

Find the module name for that class in the AS7_HOME/modules directory by looking for a path that matches the missing class. In this case, you will find 2 modules that match:

    javax/faces/api/main
    javax/faces/api/1.2

Both modules have the same module name: “javax.faces.api” but one in the main directory is for JSF 2.0 and the one located in the 1.2 directory is for JSF 1.2. If there was only one module available, we could simply create a  MANIFEST.MF file and added the module dependency. But in this case, we want to use the JSF 1.2 version and not the 2.0 version in main, so we need to be able to specify one and exclude the other. To do this, we create a jboss-deployment-structure.xml file in the EAR META-INF/ directory that contains the following data:

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
  <deployment>
  	  <dependencies>
	      <module name="javax.faces.api" slot="1.2" export="true"/>
	    </dependencies>
  </deployment>
  <sub-deployment name="jboss-seam-booking.war">
  	<exclusions>
	      <module name="javax.faces.api" slot="main"/>
	    </exclusions>
	    <dependencies>
	      <module name="javax.faces.api" slot="1.2"/>
	    </dependencies>
  </sub-deployment>
</jboss-deployment-structure>

In the "deployment" section, we add the dependency for the javax.faces.api for the JSF 1.2 module. We also add the dependency for the JSF 1.2 module in the sub-deployment section for the WAR and exclude the module for JSF 2.0.

Redeploy the application by deleting the standalone/deployments/jboss-seam-booking.ear.failed file and creating a blank jboss-seam-booking.ear.dodeploy file in the same directory.

Next Issue: java.lang.ClassNotFoundException: org.apache.commons.logging.Log

When you deploy the application, the log contains the following error:

ERROR [org.jboss.msc.service.fail] (MSC service thread 1-8) MSC00001: Failed to start service jboss.deployment.unit."jboss-seam-booking.ear".INSTALL:
org.jboss.msc.service.StartException in service jboss.deployment.unit."jboss-seam-booking.ear".INSTALL:
Failed to process phase INSTALL of deployment "jboss-seam-booking.ear"
    (.. additional logs removed ...)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.Log from [Module "deployment.jboss-seam-booking.ear.jboss-seam-booking.war:main" from Service Module Loader]

What it means:

The ClassNotFoundException indicates a missing dependency. In this case, it can not find the class org.apache.commons.logging.Log and you need to explicitly add the dependency.

How to resolve it:

Find the module name for that class in the JBOSS_HOME/modules/ directory by looking for a path that matches the missing class. In this case, you will find one module that matches the path org/apache/commons/logging/. The module name is “org.apache.commons.logging”.

Modify the jboss-deployment-structure.xml to add the module dependency to the deployment section of the file.

<module name="org.apache.commons.logging" export="true"/>

The jboss-deployment-structure.xml should now look like this:

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
  <deployment>
  	  <dependencies>
	      <module name="javax.faces.api" slot="1.2" export="true"/>
	      <module name="org.apache.commons.logging" export="true"/>
	    </dependencies>
  </deployment>
  <sub-deployment name="jboss-seam-booking.war">
  	<exclusions>
	      <module name="javax.faces.api" slot="main"/>
	    </exclusions>
	    <dependencies>
	      <module name="javax.faces.api" slot="1.2"/>
	    </dependencies>
  </sub-deployment>
</jboss-deployment-structure>

Redeploy the application by deleting the standalone/deployments/jboss-seam-booking.ear.failed file and creating a blank jboss-seam-booking.ear.dodeploy file in the same directory.

Next Issue: java.lang.ClassNotFoundException: org.dom4j.DocumentException

When you deploy the application, the log contains the following error:

ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/seam-booking]] (MSC service thread 1-3) Exception sending context initialized event to listener instance of class org.jboss.seam.servlet.SeamListener: java.lang.NoClassDefFoundError: org/dom4j/DocumentException
    (... additional logs removed ...)
Caused by: java.lang.ClassNotFoundException: org.dom4j.DocumentException from [Module "deployment.jboss-seam-booking.ear.jboss-seam.jar:main" from Service Module Loader]

What it means:

Again, the ClassNotFoundException indicates a missing dependency. In this case, it can not find the class org.dom4j.DocumentException.

How to resolve it:

Find the module name in the JBOSS_HOME/modules/ directory by looking for the org/dom4j/DocumentException. The module name is “org.dom4j”.

Modify the jboss-deployment-structure.xml to add the module dependency to the deployment section of the file.

<module name="org.dom4j" export="true"/>

The jboss-deployment-structure.xml file should now look like this:

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
  <deployment>
  	  <dependencies>
	      <module name="javax.faces.api" slot="1.2" export="true"/>
	      <module name="org.apache.commons.logging" export="true"/>
    	      <module name="org.dom4j" export="true"/>
          </dependencies>
  </deployment>
  <sub-deployment name="jboss-seam-booking.war">
  	<exclusions>
	      <module name="javax.faces.api" slot="main"/>
	    </exclusions>
	    <dependencies>
	      <module name="javax.faces.api" slot="1.2"/>
	    </dependencies>
  </sub-deployment>
</jboss-deployment-structure>

Redeploy the application by deleting the standalone/deployments/jboss-seam-booking.ear.failed file and creating a blank jboss-seam-booking.ear.dodeploy file in the same directory.

Next Issue: java.lang.ClassNotFoundException: org.hibernate.validator.InvalidValue

When you deploy the application, the log contains the following error:

ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/seam-booking]] (MSC service thread 1-6) Exception sending context initialized event to listener instance of class org.jboss.seam.servlet.SeamListener: java.lang.RuntimeException: Could not create Component: org.jboss.seam.international.statusMessages
    (... additional logs removed ...)
Caused by: java.lang.ClassNotFoundException: org.hibernate.validator.InvalidValue from [Module "deployment.jboss-seam-booking.ear.jboss-seam.jar:main" from Service Module Loader]

What it means:

Again, the ClassNotFoundException indicates a missing dependency. In this case, it can not find the class org.hibernate.validator.InvalidValue.

How to resolve it:

There is a module “org.hibernate.validator”, but the JAR does not contain the org.hibernate.validator.InvalidValue class, so adding the module dependency will not resolve this issue.

In this case, the JAR containing the class was part of the EAP 5.1 deployment. We will look for the JAR that contains the missing class in the EAP5_HOME/jboss-eap-5.1/seam/lib/ directory. To do this, open a console and type the following:

cd EAP5_HOME/jboss-eap-5.1/seam/lib
grep 'org.hibernate.validator.InvalidValue' `find . -name '*.jar'`

The result shows:

Binary file ./hibernate-validator.jar matches
Binary file ./test/hibernate-all.jar matches

In this case, we need to copy the hibernate-validator.jar to the jboss-seam-booking.ear/lib/ directory:

cp EAP5_HOME/jboss-eap-5.1/seam/lib/hibernate-validator.jar jboss-seam-booking.ear/lib

Redeploy the application by deleting the standalone/deployments/jboss-seam-booking.ear.failed file and creating a blank jboss-seam-booking.ear.dodeploy file in the same directory.

Next Issue: java.lang.InstantiationException: org.jboss.seam.jsf.SeamApplicationFactory

When you deploy the application, the log contains the following error:

INFO  [javax.enterprise.resource.webcontainer.jsf.config] (MSC service thread 1-7) Unsanitized stacktrace from failed start...: com.sun.faces.config.ConfigurationException: Factory 'javax.faces.application.ApplicationFactory' was not configured properly.
	at com.sun.faces.config.processor.FactoryConfigProcessor.verifyFactoriesExist(FactoryConfigProcessor.java:296) [jsf-impl-2.0.4-b09-jbossorg-4.jar:2.0.4-b09-jbossorg-4]
	(... additional logs removed ...)
Caused by: javax.faces.FacesException: org.jboss.seam.jsf.SeamApplicationFactory
	at javax.faces.FactoryFinder.getImplGivenPreviousImpl(FactoryFinder.java:606) [jsf-api-1.2_13.jar:1.2_13-b01-FCS]
	(... additional logs removed ...)
	at com.sun.faces.config.processor.FactoryConfigProcessor.verifyFactoriesExist(FactoryConfigProcessor.java:294) [jsf-impl-2.0.4-b09-jbossorg-4.jar:2.0.4-b09-jbossorg-4]
	... 11 more
Caused by: java.lang.InstantiationException: org.jboss.seam.jsf.SeamApplicationFactory
	at java.lang.Class.newInstance0(Class.java:340) [:1.6.0_25]
	at java.lang.Class.newInstance(Class.java:308) [:1.6.0_25]
	at javax.faces.FactoryFinder.getImplGivenPreviousImpl(FactoryFinder.java:604) [jsf-api-1.2_13.jar:1.2_13-b01-FCS]
	... 16 more

What it means:

The com.sun.faces.config.ConfigurationException and java.lang.InstantiationException indicate a dependency issue. In this case, it is not as obvious.

How to resolve it:

We need to find the module that contains the com.sun.faces classes. While there is no com.sun.faces module, there are are two com.sun.jsf-impl modules. A quick check of the jsf-impl-1.2_13.jar in the 1.2 directory shows it contains the com.sun.faces classes.

As we did with the javax.faces.FacesException ClassNotFoundException, we want to use the JSF 1.2 version and not the JSF 2.0 version in main, so we need to be able to specify one and exclude the other. We need to modify the jboss-deployment-structure.xml to add the module dependency to the deployment section of the file. We also need to add it to the WAR subdeployment and exclude the JSF 2.0 module. The file should now look like this:

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
  <deployment>
  	  <dependencies>
	      <module name="javax.faces.api" slot="1.2" export="true"/>
              <module name="com.sun.jsf-impl" slot="1.2" export="true"/>
	      <module name="org.apache.commons.logging" export="true"/>
	      <module name="org.dom4j" export="true"/>
	    </dependencies>
  </deployment>
  <sub-deployment name="jboss-seam-booking.war">
  	<exclusions>
	      <module name="javax.faces.api" slot="main"/>
	      <module name="com.sun.jsf-impl" slot="main"/>
	    </exclusions>
	    <dependencies>
	      <module name="javax.faces.api" slot="1.2"/>
              <module name="com.sun.jsf-impl" slot="1.2"/>
	    </dependencies>
  </sub-deployment>
</jboss-deployment-structure>

Redeploy the application by deleting the standalone/deployments/jboss-seam-booking.ear.failed file and creating a blank jboss-seam-booking.ear.dodeploy file in the same directory.

Next Issue: java.lang.ClassNotFoundException: org.apache.commons.collections.ArrayStack

When you deploy the application, the log contains the following error:

ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/seam-booking]] (MSC service thread 1-1) Exception sending context initialized event to listener instance of class com.sun.faces.config.ConfigureListener: java.lang.RuntimeException: com.sun.faces.config.ConfigurationException: CONFIGURATION FAILED! org.apache.commons.collections.ArrayStack from [Module "deployment.jboss-seam-booking.ear:main" from Service Module Loader]
    (... additional logs removed ...)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.collections.ArrayStack from [Module "deployment.jboss-seam-booking.ear:main" from Service Module Loader] 

What it means:

Again, the ClassNotFoundException indicates a missing dependency. In this case, it can not find the class org.apache.commons.collections.ArrayStack.

How to resolve it:

Find the module name in the JBOSS_HOME/modules/ directory by looking for the org/apache/commons/collections path. The module name is “org.apache.commons.collections”.

Modify the jboss-deployment-structure.xml to add the module dependency to the deployment section of the file.

<module name="org.apache.commons.collections" export="true"/>

The jboss-deployment-structure.xml file should now look like this:

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
  <deployment>
  	  <dependencies>
	      <module name="javax.faces.api" slot="1.2" export="true"/>
              <module name="com.sun.jsf-impl" slot="1.2" export="true"/>
	      <module name="org.apache.commons.logging" export="true"/>
	      <module name="org.dom4j" export="true"/>
	      <module name="org.apache.commons.collections" export="true"/>
	  </dependencies>
  </deployment>
  <sub-deployment name="jboss-seam-booking.war">
  	<exclusions>
	      <module name="javax.faces.api" slot="main"/>
	      <module name="com.sun.jsf-impl" slot="main"/>
	    </exclusions>
	    <dependencies>
	      <module name="javax.faces.api" slot="1.2"/>
              <module name="com.sun.jsf-impl" slot="1.2"/>
	    </dependencies>
  </sub-deployment>
</jboss-deployment-structure>

Redeploy the application by deleting the standalone/deployments/jboss-seam-booking.ear.failed file and creating a blank jboss-seam-booking.ear.dodeploy file in the same directory.

Next Issue: Services with missing/unavailable dependencies

When you deploy the application, the log contains the following error:

ERROR [org.jboss.as.deployment] (DeploymentScanner-threads - 2) {"Composite operation failed and was rolled back. Steps that failed:" => {"Operation step-2" => {"Services with missing/unavailable dependencies" => ["jboss.deployment.subunit.\"jboss-seam-booking.ear\".\"jboss-seam-booking.jar\".component.AuthenticatorAction.START missing [ jboss.naming.context.java.comp.jboss-seam-booking.\"jboss-seam-booking.jar\".AuthenticatorAction.\"env/org.jboss.seam.example.booking.AuthenticatorAction/em\" ]","jboss.deployment.subunit.\"jboss-seam-booking.ear\".\"jboss-seam-booking.jar\".component.HotelSearchingAction.START missing [ jboss.naming.context.java.comp.jboss-seam-booking.\"jboss-seam-booking.jar\".HotelSearchingAction.\"env/org.jboss.seam.example.booking.HotelSearchingAction/em\" ]","
<... additional logs removed ...>
"jboss.deployment.subunit.\"jboss-seam-booking.ear\".\"jboss-seam-booking.jar\".component.BookingListAction.START missing [ jboss.naming.context.java.comp.jboss-seam-booking.\"jboss-seam-booking.jar\".BookingListAction.\"env/org.jboss.seam.example.booking.BookingListAction/em\" ]","jboss.persistenceunit.\"jboss-seam-booking.ear/jboss-seam-booking.jar#bookingDatabase\" missing [ jboss.naming.context.java.bookingDatasource ]"]}}}

What it means:

When you get a “Services with missing/unavailable dependencies” error, look that the text within the brackets after “missing”.

In this case you see:

missing [ jboss.naming.context.java.comp.jboss-seam-booking.\"jboss-seam-booking.jar\".AuthenticatorAction.\"env/org.jboss.seam.example.booking.AuthenticatorAction/em\" ]

The “/em” indicates an Entity Manager and datasource issue.

How to resolve it:

In WildFly 8, datasource configuration has changed and needs to be defined in the standalone/configuration/standalone.xml file. Since WildFly ships with an example database that is already defined in the standalone.xml file, we will modify the persistence.xml file to use that example database. Looking in the standalone.xml file, you can see that the jndi-name for the example database is "java:jboss/datasources/ExampleDS".

Modify the jboss-seam-booking.jar/META-INF/persistence.xml file to comment the existing jta-data-source element and replace it as follows:

<!-- <jta-data-source>java:/bookingDatasource</jta-data-source> -->
<jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>

Redeploy the application by deleting the standalone/deployments/jboss-seam-booking.ear.failed file and creating a blank jboss-seam-booking.ear.dodeploy file in the same directory.

Next Issue: java.lang.ClassNotFoundException: org.hibernate.cache.HashtableCacheProvider

When you deploy the application, the log contains the following error:

ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC00001: Failed to start service jboss.persistenceunit."jboss-seam-booking.ear/jboss-seam-booking.jar#bookingDatabase": org.jboss.msc.service.StartException in service jboss.persistenceunit."jboss-seam-booking.ear/jboss-seam-booking.jar#bookingDatabase": Failed to start service
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1786)
	(... log messages removed ...)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: bookingDatabase] Unable to build EntityManagerFactory
	at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:903)
	{... log messages removed ...)
Caused by: org.hibernate.HibernateException: could not instantiate RegionFactory [org.hibernate.cache.internal.bridge.RegionFactoryCacheProviderBridge]
	at org.hibernate.cfg.SettingsFactory.createRegionFactory(SettingsFactory.java:355)
	(... log messages removed ...)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [:1.6.0_25]
	(... log messages removed ...)
Caused by: org.hibernate.cache.CacheException: could not instantiate CacheProvider [org.hibernate.cache.HashtableCacheProvider]
	at org.hibernate.cache.internal.bridge.RegionFactoryCacheProviderBridge.<init>(RegionFactoryCacheProviderBridge.java:68)
	... 20 more
Caused by: java.lang.ClassNotFoundException: org.hibernate.cache.HashtableCacheProvider from [Module "org.hibernate:main" from local module loader @12a3793 (roots: /home/sgilda/tools/jboss7/modules)]
	at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:191)
	(... log messages removed ...)

What it means:

The ClassNotFoundException indicates a missing dependency. In this case, it can not find the class org.hibernate.cache.HashtableCacheProvider.

How to resolve it:

There is no module for “org.hibernate.cache”. In this case, the JAR containing the class was part of the EAP 5.1 deployment. We will look for the JAR that contains the missing class in the EAP5_HOME/jboss-eap-5.1/seam/lib/ directory.

To do this, open a console and type the following:

cd EAP5_HOME/jboss-eap-5.1/seam/lib
grep 'org.hibernate.validator.InvalidValue' `find . -name '*.jar'`

The result shows:

Binary file ./hibernate-core.jar matches
Binary file ./test/hibernate-all.jar matches

In this case, we need to copy the hibernate-core.jar to the jboss-seam-booking.ear/lib/ directory:

cp EAP5_HOME/jboss-eap-5.1/seam/lib/hibernate-core.jar jboss-seam-booking.ear/lib

Redeploy the application by deleting the standalone/deployments/jboss-seam-booking.ear.failed file and creating a blank jboss-seam-booking.ear.dodeploy file in the same directory.

Next Issue: java.lang.ClassCastException: org.hibernate.cache.HashtableCacheProvider

When you deploy the application, the log contains the following error:

ERROR [org.jboss.msc.service.fail] (MSC service thread 1-2) MSC00001: Failed to start service jboss.persistenceunit."jboss-seam-booking.ear/jboss-seam-booking.jar#bookingDatabase": org.jboss.msc.service.StartException in service jboss.persistenceunit."jboss-seam-booking.ear/jboss-seam-booking.jar#bookingDatabase": Failed to start service
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1786)
	(... log messages removed ...)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: bookingDatabase] Unable to build EntityManagerFactory
	at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:903)
	(... log messages removed ...)
Caused by: org.hibernate.HibernateException: could not instantiate RegionFactory [org.hibernate.cache.internal.bridge.RegionFactoryCacheProviderBridge]
	at org.hibernate.cfg.SettingsFactory.createRegionFactory(SettingsFactory.java:355)
	(... log messages removed ...)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [:1.6.0_25]
	(... log messages removed ...)
Caused by: org.hibernate.cache.CacheException: could not instantiate CacheProvider [org.hibernate.cache.HashtableCacheProvider]
	at org.hibernate.cache.internal.bridge.RegionFactoryCacheProviderBridge.<init>(RegionFactoryCacheProviderBridge.java:68)
	... 20 more
Caused by: java.lang.ClassCastException: org.hibernate.cache.HashtableCacheProvider cannot be cast to org.hibernate.cache.spi.CacheProvider
	at org.hibernate.cache.internal.bridge.RegionFactoryCacheProviderBridge.<init>(RegionFactoryCacheProviderBridge.java:65)
	... 20 more

What it means:

A ClassCastException can be a result of many problems. If you look at this exception in the log, it appears the class org.hibernate.cache.HashtableCacheProvider extends org.hibernate.cache.spi.CacheProvider and is being loaded by a different class loader than the class it extends. The org.hibernate.cache.HashtableCacheProvider class is in in the hibernate-core.jar and is being loaded by the application class loader. The class it extends, org.hibernate.cache.spi.CacheProvider, is in the org/hibernate/main/hibernate-core-4.0.0.Beta1.jar and is implicitly loaded by that module.

This is not obvious, but due to changes in Hibernate 4, this problem is caused by a backward compatibility issue due moving the HashtableCacheProvider class into another package. This class was moved from the org.hibernate.cache package to the org.hibernate.cache.internal package. If you don't remove the hibernate.cache.provider_class property from the persistence.xml file, it will force the Seam application to bundle the old Hibernate libraries, resulting in ClassCastExceptions, In WildFly, you should move away from using HashtableCacheProvider and use Infinispan instead.

How to resolve it:

In WildFly, you need to comment out the hibernate.cache.provider_class property in the jboss-seam-booking.jar/META-INF persistence.xml file as follows:

<!-- <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/> -->

Redeploy the application by deleting the standalone/deployments/jboss-seam-booking.ear.failed file and creating a blank jboss-seam-booking.ear.dodeploy file in the same directory.

No more issues: Deployment errors should be resolved

At this point, the application should deploy without errors, but when you access the URL “http://localhost:8080/seam-booking/” in a browser and attempt "Account Login", you will get a runtime error “The page isn't redirecting properly”. In the next section, we will step through each runtime issue and how to debug and resolve it.

Step 3: Debug and resolve runtime errors and exceptions

First Issue: javax.naming.NameNotFoundException: Name 'jboss-seam-booking' not found in context ''

The application deploys successfully, but when you access the URL “http://localhost:8080/seam-booking/” in a browser, you get “The page isn't redirecting properly” and the log contains the following error:

SEVERE [org.jboss.seam.jsf.SeamPhaseListener] (http--127.0.0.1-8080-1) swallowing exception: java.lang.IllegalStateException: Could not start transaction
	at org.jboss.seam.jsf.SeamPhaseListener.begin(SeamPhaseListener.java:598) [jboss-seam.jar:]
	(... log messages removed ...)
Caused by: org.jboss.seam.InstantiationException: Could not instantiate Seam component: org.jboss.seam.transaction.synchronizations
	at org.jboss.seam.Component.newInstance(Component.java:2170) [jboss-seam.jar:]
	(... log messages removed ...)
Caused by: javax.naming.NameNotFoundException: Name 'jboss-seam-booking' not found in context ''
	at org.jboss.as.naming.util.NamingUtils.nameNotFoundException(NamingUtils.java:109)
	(... log messages removed ...)

What it means:

A NameNotFoundException indications a JNDI naming issue. JNDI naming rules have changed in WildFly and we need to modify the lookup names to follow the new rules.

How to resolve it:

To debug this, look earlier in the server log trace to what JNDI binding were used. Looking at the server log we see this:

15:01:16,138 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named RegisterAction in deployment unit subdeployment "jboss-seam-booking.jar" of deployment "jboss-seam-booking.ear" are as follows:

	java:global/jboss-seam-booking/jboss-seam-booking.jar/RegisterAction!org.jboss.seam.example.booking.Register
	java:app/jboss-seam-booking.jar/RegisterAction!org.jboss.seam.example.booking.Register
	java:module/RegisterAction!org.jboss.seam.example.booking.Register
	java:global/jboss-seam-booking/jboss-seam-booking.jar/RegisterAction
	java:app/jboss-seam-booking.jar/RegisterAction
	java:module/RegisterAction

15:01:16,138 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named BookingListAction in deployment unit subdeployment "jboss-seam-booking.jar" of deployment "jboss-seam-booking.ear" are as follows:

	java:global/jboss-seam-booking/jboss-seam-booking.jar/BookingListAction!org.jboss.seam.example.booking.BookingList
	java:app/jboss-seam-booking.jar/BookingListAction!org.jboss.seam.example.booking.BookingList
	java:module/BookingListAction!org.jboss.seam.example.booking.BookingList
	java:global/jboss-seam-booking/jboss-seam-booking.jar/BookingListAction
	java:app/jboss-seam-booking.jar/BookingListAction
	java:module/BookingListAction

15:01:16,138 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named HotelBookingAction in deployment unit subdeployment "jboss-seam-booking.jar" of deployment "jboss-seam-booking.ear" are as follows:

	java:global/jboss-seam-booking/jboss-seam-booking.jar/HotelBookingAction!org.jboss.seam.example.booking.HotelBooking
	java:app/jboss-seam-booking.jar/HotelBookingAction!org.jboss.seam.example.booking.HotelBooking
	java:module/HotelBookingAction!org.jboss.seam.example.booking.HotelBooking
	java:global/jboss-seam-booking/jboss-seam-booking.jar/HotelBookingAction
	java:app/jboss-seam-booking.jar/HotelBookingAction
	java:module/HotelBookingAction

15:01:16,138 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named AuthenticatorAction in deployment unit subdeployment "jboss-seam-booking.jar" of deployment "jboss-seam-booking.ear" are as follows:

	java:global/jboss-seam-booking/jboss-seam-booking.jar/AuthenticatorAction!org.jboss.seam.example.booking.Authenticator
	java:app/jboss-seam-booking.jar/AuthenticatorAction!org.jboss.seam.example.booking.Authenticator
	java:module/AuthenticatorAction!org.jboss.seam.example.booking.Authenticator
	java:global/jboss-seam-booking/jboss-seam-booking.jar/AuthenticatorAction
	java:app/jboss-seam-booking.jar/AuthenticatorAction
	java:module/AuthenticatorAction

15:01:16,139 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named ChangePasswordAction in deployment unit subdeployment "jboss-seam-booking.jar" of deployment "jboss-seam-booking.ear" are as follows:

	java:global/jboss-seam-booking/jboss-seam-booking.jar/ChangePasswordAction!org.jboss.seam.example.booking.ChangePassword
	java:app/jboss-seam-booking.jar/ChangePasswordAction!org.jboss.seam.example.booking.ChangePassword
	java:module/ChangePasswordAction!org.jboss.seam.example.booking.ChangePassword
	java:global/jboss-seam-booking/jboss-seam-booking.jar/ChangePasswordAction
	java:app/jboss-seam-booking.jar/ChangePasswordAction
	java:module/ChangePasswordAction

15:01:16,139 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named HotelSearchingAction in deployment unit subdeployment "jboss-seam-booking.jar" of deployment "jboss-seam-booking.ear" are as follows:

	java:global/jboss-seam-booking/jboss-seam-booking.jar/HotelSearchingAction!org.jboss.seam.example.booking.HotelSearching
	java:app/jboss-seam-booking.jar/HotelSearchingAction!org.jboss.seam.example.booking.HotelSearching
	java:module/HotelSearchingAction!org.jboss.seam.example.booking.HotelSearching
	java:global/jboss-seam-booking/jboss-seam-booking.jar/HotelSearchingAction
	java:app/jboss-seam-booking.jar/HotelSearchingAction
	java:module/HotelSearchingAction

15:01:16,140 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-6) JNDI bindings for session bean named EjbSynchronizations in deployment unit subdeployment "jboss-seam.jar" of deployment "jboss-seam-booking.ear" are as follows:

	java:global/jboss-seam-booking/jboss-seam/EjbSynchronizations!org.jboss.seam.transaction.LocalEjbSynchronizations
	java:app/jboss-seam/EjbSynchronizations!org.jboss.seam.transaction.LocalEjbSynchronizations
	java:module/EjbSynchronizations!org.jboss.seam.transaction.LocalEjbSynchronizations
	java:global/jboss-seam-booking/jboss-seam/EjbSynchronizations
	java:app/jboss-seam/EjbSynchronizations
	java:module/EjbSynchronizations

15:01:16,140 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-6) JNDI bindings for session bean named TimerServiceDispatcher in deployment unit subdeployment "jboss-seam.jar" of deployment "jboss-seam-booking.ear" are as follows:

	java:global/jboss-seam-booking/jboss-seam/TimerServiceDispatcher!org.jboss.seam.async.LocalTimerServiceDispatcher
	java:app/jboss-seam/TimerServiceDispatcher!org.jboss.seam.async.LocalTimerServiceDispatcher
	java:module/TimerServiceDispatcher!org.jboss.seam.async.LocalTimerServiceDispatcher
	java:global/jboss-seam-booking/jboss-seam/TimerServiceDispatcher
	java:app/jboss-seam/TimerServiceDispatcher
	java:module/TimerServiceDispatcher

We need to modify the WAR's lib/components.xml file to use the new JNDI bindings. In the log, note the EJB JNDI bindings all start with "java:app/jboss-seam-booking.jar"

Replace the <core:init> element as follows:

<!--     <core:init jndi-pattern="jboss-seam-booking/#{ejbName}/local" debug="true" distributable="false"/> -->
<core:init jndi-pattern="java:app/jboss-seam-booking.jar/#{ejbName}" debug="true" distributable="false"/>

Next, we need to add the EjbSynchronizations and TimerServiceDispatcher JNDI bindings. Add the following component elements to the file:

<component class="org.jboss.seam.transaction.EjbSynchronizations" jndi-name="java:app/jboss-seam/EjbSynchronizations"/>
<component class="org.jboss.seam.async.TimerServiceDispatcher" jndi-name="java:app/jboss-seam/TimerServiceDispatcher"/>

The components.xml file should now look like this:

<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://jboss.com/products/seam/components"
            xmlns:core="http://jboss.com/products/seam/core"
            xmlns:security="http://jboss.com/products/seam/security"
            xmlns:transaction="http://jboss.com/products/seam/transaction"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation=
                "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.2.xsd
                 http://jboss.com/products/seam/transaction http://jboss.com/products/seam/transaction-2.2.xsd
                 http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.2.xsd
                 http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.2.xsd">

    <!-- <core:init jndi-pattern="jboss-seam-booking/#{ejbName}/local" debug="true" distributable="false"/> -->
    <core:init jndi-pattern="java:app/jboss-seam-booking.jar/#{ejbName}" debug="true" distributable="false"/>

    <core:manager conversation-timeout="120000"
                  concurrent-request-timeout="500"
                  conversation-id-parameter="cid"/>

    <transaction:ejb-transaction/>

    <security:identity authenticate-method="#{authenticator.authenticate}"/>

    <component class="org.jboss.seam.transaction.EjbSynchronizations"
            jndi-name="java:app/jboss-seam/EjbSynchronizations"/>
    <component class="org.jboss.seam.async.TimerServiceDispatcher"
            jndi-name="java:app/jboss-seam/TimerServiceDispatcher"/>
</components>

Redeploy the application by deleting the standalone/deployments/jboss-seam-booking.ear.failed file and creating a blank jboss-seam-booking.ear.dodeploy file in the same directory.

At this point, the application should deploy and run without error. When you access the URL “http://localhost:8080/seam-booking/” in a browser, you will be able to login successfully.

Step 4: Access the application

Access the URL “http://localhost:8080/seam-booking/” in a browser and login with demo/demo. You should the Booking welcome page.

Summary of Changes

Although it would be much more efficient to determine dependencies in advance and add the implicit dependencies in one step, this exercise shows how problems appear in the log and provides some information on how to debug and resolve them.

The following is a summary of changes made to the application when migrating it to WildFly:

  1. We created a jboss-deployment-structure.xml file in the EAR's META-INF/ directory. We added "dependencies" and "exclusions" to resolve ClassNotFoundExceptions. This file contains the following data:

    <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
      <deployment>
      	  <dependencies>
    	      <module name="javax.faces.api" slot="1.2" export="true"/>
    	      <module name="com.sun.jsf-impl" slot="1.2" export="true"/>
    	      <module name="org.apache.commons.logging" export="true"/>
        	      <module name="org.dom4j" export="true"/>
    	      <module name="org.apache.commons.collections" export="true"/>
    	    </dependencies>
      </deployment>
      <sub-deployment name="jboss-seam-booking.war">
      	<exclusions>
    	      <module name="javax.faces.api" slot="main"/>
    	      <module name="com.sun.jsf-impl" slot="main"/>
    	    </exclusions>
    	    <dependencies>
    	      <module name="javax.faces.api" slot="1.2"/>
    	      <module name="com.sun.jsf-impl" slot="1.2"/>
    	    </dependencies>
      </sub-deployment>
    </jboss-deployment-structure>
  2. We copied the following JARs from the EAP5_HOME/jboss-eap-5.1/seam/lib/ directory to the jboss-seam-booking.ear/lib/ directory to resolve ClassNotFoundExceptions:

    hibernate-core.jar
    hibernate-validator.jar
  3. We modified the {{jboss-seam-booking.jar/META-INF/persistence.xml} file as follows.

    1. First, we changed the jta-data-source element to use the Example database that ships with AS7:

      <!-- <jta-data-source>java:/bookingDatasource</jta-data-source> -->
      <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
    2. Next, we commented out the hibernate.cache.provider_class property:

      <!-- <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/> -->
  4. We modified the WAR's lib/components.xml file to use the new JNDI bindings

    1. We replaced the <core:init> existing element as follows:

      <!-- <core:init jndi-pattern="jboss-seam-booking/#{ejbName}/local" debug="true" distributable="false"/> -->
      <core:init jndi-pattern="java:app/jboss-seam-booking.jar/#{ejbName}" debug="true" distributable="false"/>
    2. We added component elements for the "EjbSynchronizations" and "TimerServiceDispatcher" JNDI bindings

       <component class="org.jboss.seam.transaction.EjbSynchronizations" jndi-name="java:app/jboss-seam/EjbSynchronizations"/>
       <component class="org.jboss.seam.async.TimerServiceDispatcher" jndi-name="java:app/jboss-seam/TimerServiceDispatcher"/>

The unmodified EAR from EAP 5.1 (jboss-seam-booking-eap51.ear.tar.gz) and the EAR as modified to run on AS7 (jboss-seam-booking-as7.ear.tar.gz) are attached to this document.

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-13 13:55:08 UTC, last content change 2013-12-18 23:31:55 UTC.